/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package fachada;

import java.util.ArrayList;
import java.util.Iterator;
import pap.pickapartner.Convite;
import pap.pickapartner.GrupoCarona;
import pap.pickapartner.Horario;
import pap.pickapartner.Usuario;
import sun.misc.Compare;
import sun.misc.Sort;



public class ControladorCaronas {

    //Formar grupos de caronas, Escalonador das caronas, 
    private ArrayList<Usuario> usuarios;

    public ControladorCaronas(ArrayList<Usuario> usuarios) {
        this.usuarios = usuarios;
    }
    
    
    private void escalonarGrupos() {
        ArrayList<Convite> convites = new ArrayList<Convite>();
        //Map<Convite, GrupoCarona> convites = new HashMap<Convite, GrupoCarona>();
        Iterator<String> bairros = null; //Todos os Bairros: Consulta em tb_Localizacao
        while(bairros.hasNext()) {
            Iterator<Horario> horarios = null; //Todos os Horarios: Consulta em tb_Horarios
            while(horarios.hasNext()) {
                Horario nextHorario = horarios.next();
                ArrayList<GrupoCarona> grupo = null; //Seleciona grupos no Bairro, Horario
                ArrayList<Usuario> usuariosBairroHorario = null; //Seleciona usuarios por Bairro, Horario e que nao pertecem a grupo
                Iterator<GrupoCarona> grupoIt = grupo.iterator();
                while(grupoIt.hasNext()) {
                    GrupoCarona next = grupoIt.next();
                    if(next.estaFechado())
                        grupo.remove(next);
                }

                while(!grupo.isEmpty() && !usuariosBairroHorario.isEmpty()) {
                    Usuario maxVagasVeiculo = maxVagasVeiculo(usuariosBairroHorario);
                    GrupoCarona maxTamanhoMaximo = maxTamanhoMaximo(grupo);
                    convites.add(new Convite(maxVagasVeiculo, maxTamanhoMaximo, nextHorario));
                    //convites.put(new Convite(maxVagasVeiculo, nextHorario), maxTamanhoMaximo);
                    if(maxTamanhoMaximo.estaFechado())
                        grupo.remove(maxTamanhoMaximo);
                }
                if(!usuariosBairroHorario.isEmpty()) {
                    criarGrupos(convites, usuariosBairroHorario, nextHorario);
                }
            }
        }
    }
    
    private Usuario maxVagasVeiculo(ArrayList<Usuario> usuarios) {
        Iterator<Usuario> it = usuarios.iterator();
        Usuario usuario = it.next();
        while(it.hasNext()) {
            Usuario next = it.next();
            if(usuario.maxVeiculosVagas() < next.maxVeiculosVagas())
                usuario = next;
        }
        return usuario;
    }
    
    private GrupoCarona maxTamanhoMaximo(ArrayList<GrupoCarona> grupos) {
        Iterator<GrupoCarona> it = grupos.iterator();
        GrupoCarona grupo = it.next();
        while(it.hasNext()) {
            GrupoCarona next = it.next();
            if(grupo.tamanhoMaximo() < next.tamanhoMaximo())
                grupo = next;
        }
        return grupo;
    }
    
    private void criarGrupos(ArrayList<Convite> convites, ArrayList<Usuario> usuarios, Horario horario) {
        Object[] usuariosArray = usuarios.toArray();
        Sort.quicksort(usuariosArray, new Compare() {

            public int doCompare(Object arg0, Object arg1) {
                int maxVagasA = ((Usuario)arg0).maxVeiculosVagas();
                int maxVagasB = ((Usuario)arg1).maxVeiculosVagas();
                return (maxVagasB - maxVagasA); //Ordem decrescente
            }
        } );
        
       ArrayList<Usuario> usuariosBairroHorario = new ArrayList<Usuario>(usuariosArray.length);
       for(int i = 0; i < usuariosArray.length; i++) {
            usuariosBairroHorario.add((Usuario)usuariosArray[i]);
        }
       
       while(!usuariosBairroHorario.isEmpty()) {
           int maxNoVagas = usuariosBairroHorario.get(0).maxVeiculosVagas();
           int i = ((usuariosBairroHorario.size()-1) > maxNoVagas)? maxNoVagas : (usuariosBairroHorario.size()-1);
           while(usuariosBairroHorario.get(i).maxVeiculosVagas() < i)
               --i;
           ArrayList<Usuario> grupo = new ArrayList<Usuario>();
           for(int j = 0; j <= i; j++) {
               Usuario usuario = usuariosBairroHorario.remove(j);
               grupo.add(usuario);
               convites.add(new Convite(usuario, new GrupoCarona(grupo), horario));
           }
       } 
    }
    
    
}
